home *** CD-ROM | disk | FTP | other *** search
-
- Make the (base) ~Hash_Table() destructor method inline.
-
- Get rid of the Hash_Table<Tkey,Tval>::Hash_Table<Tkey,Tval> () constructor
- and give the constructor that takes a size a default argument:
- Hash_Table<Tkey,Tval>::Hash_Table<Tkey,Tval> (int n=1) : (n) {
- Do the same for the base Hash_Table class.
-
- Move the "traversed" flag in the current position out of Hash_Table, and
- only support it in the Set class.
-
- Use the following for setting current position:
- #define make_current_position(hash, index) ((hash << 8) | index)
- this->current_position.data = make_current_position(hash, index);
- This helps out compilers that don't optimize well (-g option)
- and will be faster, if the "traversed" flag is left in.
-
- The resize method can be improved by using the overloaded operator new
- in cfront 2.0 to only construct the new buckets, avoid calling the
- destructor for the old buckets, and avoid operator= by using memcpy (see
- Vector<Type>::resize)
-
- Don't try saving the current position in the remove method. Since it
- doesn't always work, it should never be done.
-
- Re-write Boolean Hash_Table<Tkey,Tval>::remove (const Tkey& key);
- to do a find(key) followed by remove();
- (this reduces the amount of code generated for each hash table)
-
- Operator= shouldn't make the sizes of the two hash tables the same,
- it should just copy the contents. The current algorithm should be
- an optimization for the case where the two sizes are already equal,
- or less than.
-
- Operator== shouldn't depend on the two hash table's having the same
- number of buckets. It should first check for the number of entries
- being the same (which it does), then for each element in the first hash
- table, do a find on the second, and compare the values. The current
- algorithm should be used as an optimization for the case where the two
- hash tables have the same number of buckets.
- DONE
-
- find, put, get and remove all have the following inner-loop code:
- long prime = hash_primes[this->current_bucket]; // Prime number of buckets
- unsigned long hash = ((*this->h_function)(key)) % prime; // Get hash value
- int index = this->items_in_buckets[hash];
- for (int i = 0; i < index; i++) // For each item
- if ((*this->compare_keys)(key,this->table[hash].data[i].key) == TRUE)
- //DO SOMETHING
-
- Get rid of the function call in the inner loop by making compare_keys
- default to NULL, and moving the default code to a general purpose find
- method. Do the same for default_hash.
- The above code can be replaced with:
-
- unsigned long hash;
- int i = this->internal_find(key, &hash);
- if (i < 0) DO_SOMETHING
- else DO_SOMETHING_ELSE
-
- // Returns bucket index, or -1 if not found
- // If hash_return is non-null, return the hash value
- // If hash_return is null, this function returns the hash value
- // (this feature is used by the resize method)
-
- long Hash_Table<Tkey, Tval>::internal_find(Tkey key, long* hash_return) {
- long prime = hash_primes[this->current_bucket]; // Prime number of buckets
- long hash;
- //
- // Get the hash value
- //
- if (this->h_function != NULL)
- hash = ((*this->h_function)(key)) % prime;
- else {
- #if ISSAME(Tkey, charP) || ISSAME(Tkey, String)
- hash = sxhash(key) % prime;
- #else
- if (sizeof (key) <= 4)
- hash = (((unsigned long) key) >> 3) % prime;
- else
- hash = sxhash((char*) &key) % prime;
- #endif
- }
- if (hash_return == NULL)
- return hash;
- else
- hash_return = hash;
- //
- // Find the bucket entry
- //
- int index = this->items_in_buckets[hash];
- Tkey##_##Tval##_hash_pair bucket[BUCKET_SIZE] = this->table[hash].data;
- if (this->compare_keys == NULL) { // DEFAULT COMPARE FUNCTION
- #if ISSAME(T1, charP)
- #ifndef C_STRINGH
- extern int strcmp (const char*, const char*);
- #endif
- for (int i = 0; i < index; i++) // For each item
- if (!strcmp(key,bucket[i].key))
- return i;
- #else
- for (int i = 0; i < index; i++) // For each item
- if (key == bucket[i].key)
- return i;
- #endif
-
- } else { // VARIABLE COMPARE FUNCTION
- for (int i = 0; i < index; i++) // For each item
- if ((*this->compare_keys)(key, bucket[i].key))
- return i;
- }
- return -1;
- }
-
- This method replaces default_hash and Default_Hash_Compare. In
- addition, it eliminates several function calls in all the lookup
- methods, and reduces code duplication (i.e. reduces the amount of code
- generated for each hash table)
-